package com.github.excel.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.code.starter.util.RedisUtils;
import com.code.starter.util.RequestUtils;
import com.github.excel.constant.RedisKeyPrefix;
import com.github.excel.remote.OtherRequest;
import com.github.excel.service.IDownloadFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ValidationException;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class DownloadFileServiceImpl implements IDownloadFileService {

    @Autowired
    private OtherRequest otherRequest;

    @Override
    public String getFileDownLoadTaskId(List<String> idList) {
        if (CollUtil.isEmpty(idList)){
            throw new ValidateException("请选择需要下载的数据信息！");
        }

        //ToDo 封装下载链接
        List<Map<String, String>> theImgInfoList = new ArrayList<Map<String,String>>();

        if (CollUtil.isEmpty(theImgInfoList)) {
            throw new ValidationException("无可下载数据");
        }
        //任务id
        String taskId = IdUtil.fastSimpleUUID();
        RedisUtils.set(RedisKeyPrefix.getKey(RedisKeyPrefix.USER_INFO_STRING,taskId), JSONArray.toJSONString(theImgInfoList));
        return taskId;
    }

    @Override
    public void getFileZipByTaskId(String taskId) {
        if (StrUtil.isBlank(taskId)){
            return;
        }
        Boolean hasKeyFlag = RedisUtils.hasKey(RedisKeyPrefix.getKey(RedisKeyPrefix.USER_INFO_STRING, taskId));
        if (!hasKeyFlag){
            return;
        }
        String downloadFileStr = RedisKeyPrefix.getKey(RedisKeyPrefix.USER_INFO_STRING);
        if (StrUtil.isBlank(downloadFileStr)){
            return;
        }
        List<JSONObject> downloadFileList = JSONArray.parseArray(downloadFileStr, JSONObject.class);
        this.getFileZipByFileList(RequestUtils.getResponse(),downloadFileList);
    }

    /**
     * 获取下载文件zip压缩包
     */
    public void getFileZipByFileList(HttpServletResponse response, List<JSONObject> contentList) {
        if (CollUtil.isEmpty(contentList)) {
            return;
        }
        OutputStream outputStream = null;
        ZipOutputStream zipOutStream = null;
        try {
            String downloadName = URLEncoder.encode("文件信息.zip", "UTF-8");
            response.reset();
            response.setHeader("Content-Disposition", "attachment;filename=" + downloadName);
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setCharacterEncoding("utf-8");

            outputStream = response.getOutputStream();
            zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
            // -- 设置压缩方法
            zipOutStream.setMethod(ZipOutputStream.DEFLATED);
            for (JSONObject theObject : contentList) {
                String imgName = theObject.getString("imgName");
                String imgUrl = theObject.getString("imgUrl");
                String ext = imgUrl.substring(imgUrl.lastIndexOf(".") + 1);
                String theImgBase64 = otherRequest.getFileBase64(imgUrl);
                if (StrUtil.isNotBlank(theImgBase64)) {
                    byte[] theByte = Base64.getDecoder().decode(theImgBase64);
                    String fileName = imgName + "." + ext;
                    zipOutStream.putNextEntry(new ZipEntry(fileName));
                    zipOutStream.write(theByte);
                    zipOutStream.closeEntry();
                }
            }

            zipOutStream.flush();
            zipOutStream.close();
            outputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (Objects.nonNull(zipOutStream)) {
                    zipOutStream.flush();
                    zipOutStream.close();
                }
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
